﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using EjotyI;


namespace EjotyI
{
    class Program
    {
        static void Main(string[] args)
        {
            bool loopon;            //the loop initializer
            StreamReader myStr;     //the IO tool
            string address;     //where the file is located
            string text;        //to hold the entire file's contents
            Computer comp = new Computer();     //declare object refrence

            Console.WriteLine("Welcome, This Program interprets files written in Ejoty 0.9.5");
            for (loopon = true; loopon == true; )   //main loop
            {
                Console.WriteLine("Enter the path of the file you wish to interpret:");
                address = Console.ReadLine();   //store the address of the file
                if (File.Exists(address))       //check to make sure file exists
                {
                    Console.WriteLine("File Found");    //tell user that the file exists
                    myStr = File.OpenText(address);     //open access to the file
                    text = myStr.ReadToEnd();           //read the contents of the file and store in text
                    char[] delimiters = {' ','|','\t'};              //seperate the indivdual commands using "/"
                    comp.input = text.Split(delimiters);     //split text into individual commands, store in input
                    //time to begin the actual interpretation
                    //first we generate the tokens
                    comp.tokens();
                    //now we create a loop to execute the file to the end
                    for (; comp.a < comp.myToken.tokens.Length; comp.a++)
                    {
                        comp.intertok(comp.myToken.tokens[comp.a]);
                    }
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Could not find file.");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }
        }
    }
    //class computer handles all non complex commands and the virtualization of a turing machine
    class Computer
    {
        public string[] input;     //the array holding individual commands
        public int a = 0;          //file command reader counter, a
        public int[] pointer = new int[32]; //used to hold the cells value
        public Tokenizer myToken;   //declare the token class
        public void tokens()
        {
            myToken = new Tokenizer(input);     //convert strings to tokens
        }
        public void intertok(int input)
        {
            //switch to interpret tokens
            switch (input)
            {
                //define "set"
                case 45:
                    set();
                    break;
                //define "coutput"
                case 50:
                    string text1 = Ejoty.EjotyIO.IntToString(pointer[myToken.tokens[++a]]);
                    Console.WriteLine();
                    Console.WriteLine(text1);
                    break;
                //define "soutput"
                case 51:
                    Console.WriteLine();
                    Console.WriteLine(pointer[myToken.tokens[a++]]);
                    break;
                //define "if"
                case 46:
                    branch();
                    break;
                //define "while"
                case 52:
                    loop();
                    break;
            }
        }
        //function for "set"
        private void set()
        {
            a++;
            if (myToken.tokens[a] < 32)
            {
                int assignto = myToken.tokens[a];
                a++;
                if (myToken.tokens[a] == 34)
                {
                    //interpret the assignment features of "set"
					a++;
                    for (; myToken.tokens[a] != 55; a++)
                    {
                        switch (myToken.tokens[a])
                        {
                            //add one to assignment
                            case 32:
                                pointer[assignto]++;
                                Console.WriteLine("+1");
                                break;
                            //subtract one from assignment
                            case 33:
                                pointer[assignto]--;
                                break;
                            //multiply number before and after symbol
                            case 35:
                                pointer[assignto] = pointer[myToken.tokens[a - 1]] * pointer[myToken.tokens[a + 1]];
                                break;
                            //divide the number before by the the number after the token
                            case 36:
                                pointer[assignto] = pointer[myToken.tokens[a - 1]] / pointer[myToken.tokens[a + 1]];
                                break;
                            //add the number before onto the number after
                            case 37:
                                pointer[assignto] = pointer[myToken.tokens[a - 1]] + pointer[myToken.tokens[a + 1]];
                                break;
                            //subtraction
                            case 38:
                                pointer[assignto] = pointer[myToken.tokens[a - 1]] - pointer[myToken.tokens[a + 1]];
                                break;
                            //define "cinput"
                            case 48:
                                Console.WriteLine();
                                string text2 = Console.ReadLine();
                                pointer[assignto] = Ejoty.EjotyIO.CharToInt(text2);
                                break;
                        }
                    }
                }
            }
        }
        //function for "if"
        private void branch()
        {
            a += 2;
            switch (myToken.tokens[a])
            {
                //>
                case 39:
                    if (pointer[myToken.tokens[a - 1]] > pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
                //<
                case 40:
                    if (pointer[myToken.tokens[a - 1]] < pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
                //>=
                case 41:
                    if (pointer[myToken.tokens[a - 1]] >= pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
                //<=
                case 42:
                    if (pointer[myToken.tokens[a - 1]] <= pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
                //=
                case 43:
                    if (pointer[myToken.tokens[a - 1]] == pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
                //!=
                case 44:
                    if (pointer[myToken.tokens[a - 1]] != pointer[myToken.tokens[++a]])
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                    }
                    break;
            }
        }
        //function for "while"
        private void loop()
        {
            a += 2;
            switch (myToken.tokens[a])
            {
                //>
                case 39:
                    int loopstart = a;
                    bool loopon = false;
                    if (pointer[myToken.tokens[a - 1]] > pointer[myToken.tokens[++a]])
                    {
                        loopon = true;
                    }
                    while (loopon == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart;
                        }
                        if (pointer[myToken.tokens[a - 1]] > pointer[myToken.tokens[++a]])
                        {
                            loopon = true;
                        }
                        else
                        {
                            loopon = false;
                        }
                    }
                    break;
                //<
                case 40:
                    int loopstart1 = a;
                    bool loopon1 = false;
                    if (pointer[myToken.tokens[a - 1]] < pointer[myToken.tokens[++a]])
                    {
                        loopon1 = true;
                    }
                    while (loopon1 == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart1;
                        }
                        if (pointer[myToken.tokens[a - 1]] < pointer[myToken.tokens[++a]])
                        {
                            loopon1 = true;
                        }
                        else
                        {
                            loopon1 = false;
                        }
                    }
                    break;
                //>=
                case 41:
                    int loopstart2 = a;
                    bool loopon2 = false;
                    if (pointer[myToken.tokens[a - 1]] >= pointer[myToken.tokens[++a]])
                    {
                        loopon2 = true;
                    }
                    while (loopon2 == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart2;
                        }
                        if (pointer[myToken.tokens[a - 1]] >= pointer[myToken.tokens[++a]])
                        {
                            loopon2 = true;
                        }
                        else
                        {
                            loopon2 = false;
                        }
                    }
                    break;
                //<=
                case 42:
                    int loopstart3 = a;
                    bool loopon3 = false;
                    if (pointer[myToken.tokens[a - 1]] <= pointer[myToken.tokens[++a]])
                    {
                        loopon3 = true;
                    }
                    while (loopon3 == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart3;
                        }
                        if (pointer[myToken.tokens[a - 1]] <= pointer[myToken.tokens[++a]])
                        {
                            loopon3 = true;
                        }
                        else
                        {
                            loopon3 = false;
                        }
                    }
                    break;
                //=
                case 43:
                    int loopstart4 = a;
                    bool loopon4 = false;
                    if (pointer[myToken.tokens[a - 1]] == pointer[myToken.tokens[++a]])
                    {
                        loopon4 = true;
                    }
                    while (loopon4 == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart4;
                        }
                        if (pointer[myToken.tokens[a - 1]] == pointer[myToken.tokens[++a]])
                        {
                            loopon4 = true;
                        }
                        else
                        {
                            loopon4 = false;
                        }
                    }
                    break;
                //!=
                case 44:
                    int loopstart5 = a;
                    bool loopon5 = false;
                    if (pointer[myToken.tokens[a - 1]] != pointer[myToken.tokens[++a]])
                    {
                        loopon5 = true;
                    }
                    while (loopon5 == true)
                    {
                        for (; myToken.tokens[a] != 47; a++)
                        {
                            intertok(myToken.tokens[a]);
                        }
                        if (myToken.tokens[a] == 47)
                        {
                            a = loopstart5;
                        }
                        if (pointer[myToken.tokens[a - 1]] != pointer[myToken.tokens[++a]])
                        {
                            loopon5 = true;
                        }
                        else
                        {
                            loopon5 = false;
                        }
                    }
                    break;
            }
        }
    }
}
